<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\common\library\Ems;
use app\common\library\Sms;
use EasyWeChat\Factory;
use fast\Random;
use think\Config;
use think\Validate;
use think\Env;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\model\Third;
use app\admin\model\sport\Area as AreaModel;
use app\admin\model\sport\SUser as ScoreUserModel;
use app\admin\model\sport\SUserDetail as ScoreUserDetailModel;
use app\admin\model\sport\ScoreType as ScoreTypeModel;
use app\admin\model\sport\Score as ScoreModel;
use app\admin\model\sport\Setting as SettingModel;
use app\admin\model\sport\Batch as BatchModel;
use app\common\library\Batch;
use app\common\library\Score as ScoreLib;

/**
 * 会员接口
 */
class User extends Api
{

    const MIDDLE = 'middle';
    const SENIOR = 'senior';
    const TASKLEN = 3;
    const CONSUME_TIME = 5; // 处理2条花费的时间 秒
    const CRONTAB_MIN = 2; // 批量处理程序间隔运行的分钟数
    protected $noNeedLogin = ['login', 'mobilelogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third', 'logout', 'postUpload'];
    protected $noNeedRight = '*';
    protected $_user = null;
   
    protected $scoreTypes = [
        'middle'  => '中考体育评分',
        'senior'  => '高考体育评分',
    ];
    protected $units = [
        'ms'  => '分.秒',
        'meter'  => '米',
        'cmeter'  => '厘米',
        'sec' => '秒',
        'an' => '个',
    ];
    protected $sexs = [
        '1'  => '男生',
        '2'  => '女生',
    ];

    public function _initialize()
    {
        parent::_initialize();
        $this->_user = $this->auth->getUser();

        if (!Config::get('fastadmin.usercenter')) {
            $this->error(__('User center already closed'));
        }

    }
    // 业务部分 

    public function checkBatch()
    {
        $this->_checkBatch();
        $this->success('操作成功');
    }

    public function downloadTemplate()
    {
        // 判断权限
        $this->_checkBatch();
        $areaId = input('get.area_id');
        $sportType = input('get.score_type');
        if (empty($areaId) || empty($sportType)) {
            $this->error('缺少参数');
        }
        $areaModel = AreaModel::where('id', $areaId)->find();
        if (empty($areaModel)) {
            $this->error('暂无匹配区域的模版记录');
        }
        if ($sportType == self::MIDDLE && empty($areaModel->middle_template)) {
            $this->error('暂无对应模版');
        }
        if ($sportType == self::SENIOR && empty($areaModel->senior_template)) {
            $this->error('暂无对应模版');
        }
        $filename = $sportType == self::MIDDLE ? $areaModel->middle_template : $areaModel->senior_template; 
        $url = cdnurl($filename, true);
        $res = [];
        $res['url'] = $url;
        $this->success('ok', $res);
    }

    public function uploadTemplate() 
    {
        $this->_checkBatch();
        Config::set('default_return_type', 'json');
        //必须设定cdnurl为空,否则cdnurl函数计算错误
        Config::set('upload.cdnurl', '');
        $attachment = null;
        //默认普通上传文件
        $file = $this->request->file('file');
        try {
            $upload = new Upload($file);
            $attachment = $upload->upload();
        } catch (UploadException $e) {
            $this->error($e->getMessage());
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $taskId = $this->request->post('task_id', 0);

        $batchLib = new Batch();
        $sourcefilename = $attachment->url;
        $curPath = dirname(dirname(APP_PATH));
        $res = $batchLib->handleExcel($curPath . $sourcefilename);
        $header = $res[0];
        $areaId = $res[1];
        $scoreType = $res[2];
        $totalRecords = $res[3];
        if ($totalRecords == 0) {
            $this->error('没有要分析的数据');
        }
        if (empty($areaId) || empty($scoreType)) {
            $this->error('上传的模版非标准');
        }

        // $totalTime = ceil($totalRecords / 2 / self::CONSUME_TIME);
        $totalTime = self::CONSUME_TIME;
        if (empty($taskId)) {
            $count = BatchModel::where('user_id', $this->_user->id)->count()+1;
            $countLen = strlen($count);
            $taskId = date('Ymd') . "-";
            if ($countLen != self::TASKLEN) {
                $taskId .= str_repeat('0', self::TASKLEN - $countLen) . $count;
            } else {
                $taskId .= $count;
            }

            $batchModel = new BatchModel();  
            $batchModel->user_id = $this->_user->id;
            $batchModel->area_id = $areaId;
            $batchModel->score_type = $scoreType;
            $batchModel->score_header = $header;
            $batchModel->task_id = $taskId;
            $batchModel->source_filename = $sourcefilename;
            $batchModel->total_records = $totalRecords;
            $batchModel->save();
        } else {
            $batchModel = BatchModel::where('task_id', $taskId)->find();
            if (empty($batchModel)) {
                $this->error('批次信息不存在');
            }
            $taskId = $batchModel->task_id;
            $batchModel->area_id = $areaId;
            $batchModel->score_type = $scoreType;
            $batchModel->score_header = $header;
            $batchModel->source_filename = $sourcefilename;
            $batchModel->total_records = $totalRecords;
            $batchModel->save();
        }

        $res = [];
        $res['task_id'] = $taskId;
        $res['estimated_time'] = date('H:i', time() + $totalTime + self::CRONTAB_MIN * 60);
        $this->success('ok', $res);
    }

    public function postUpload()
    {
        $t = input('post.t');
        if (empty($t)) {
            exit('缺少参数');
        }
        $uuid = base64_decode($t);
        // 查看uuid是否有效
        $batchModel = BatchModel::where('uniq_id', $uuid)->where('source_filename is null')->find();
        if (empty($batchModel)) {
            exit('无效的链接');
        }
        $attachment = null;
        //默认普通上传文件
        $file = $this->request->file('file');
        try {
            $upload = new Upload($file);
            $attachment = $upload->upload();
        } catch (UploadException $e) {
            exit($e->getMessage());
        } catch (\Exception $e) {
            exit($e->getMessage());
        }

        $batchLib = new Batch();
        $sourcefilename = $attachment->url;
        $curPath = dirname(dirname(APP_PATH));
        $res = $batchLib->handleExcel($curPath . $sourcefilename);
        $header = $res[0];
        $areaId = $res[1];
        $scoreType = $res[2];
        $totalRecords = $res[3];
        if ($totalRecords == 0) {
            exit('没有要分析的数据');
        }
        if (empty($areaId) || empty($scoreType)) {
            exit('上传的模版非标准');
        }

        // $totalTime = ceil($totalRecords / 2 / self::CONSUME_TIME);
        $totalTime = self::CONSUME_TIME;

        $count = BatchModel::where('user_id', $batchModel->user_id)->count()+1;
        $countLen = strlen($count);
        $taskId = date('Ymd') . "-";
        if ($countLen != self::TASKLEN) {
            $taskId .= str_repeat('0', self::TASKLEN - $countLen) . $count;
        } else {
            $taskId .= $count;
        }

        $batchModel->task_id = $taskId;
        $batchModel->area_id = $areaId;
        $batchModel->score_type = $scoreType;
        $batchModel->score_header = $header;
        $batchModel->source_filename = $sourcefilename;
        $batchModel->total_records = $totalRecords;
        $batchModel->save();
        $estimatedTime = date('H:i', time() + $totalTime + self::CRONTAB_MIN * 60);

        exit('上传完毕，请到小程序中查看批量处理任务进度<br />任务ID：' . $taskId . '<br />预估计算完成时间：' . $estimatedTime);
    }

    public function getUploadPath()
    {
        $this->_checkBatch();
        $areaId = input('post.area_id');
        $scoreType = input('post.score_type');
        if (empty($areaId) || empty($scoreType)) {
            $this->error('缺少参数');
        }
        $batchModel = BatchModel::where('user_id', $this->_user->id)->where('area_id', $areaId)
            ->where('score_type', $scoreType)
            ->where('source_filename is null')
            ->where('uniq_id is not null')
            ->find();
        $uuid = Random::uuid();
        if (empty($batchModel)) {
            $batchModel = new BatchModel();  
            $batchModel->user_id = $this->_user->id;
            $batchModel->area_id = $areaId;
            $batchModel->score_type = $scoreType;
            $batchModel->uniq_id = $uuid;
            $batchModel->save();
        } else {
            $uuid = $batchModel->uniq_id;
        }

        $res = [];
        $res['url'] = request()->domain() . "/index/user/upload.html?t=" . base64_encode($uuid);

        $this->success('ok', $res);
    
    }

    public function getBatchList()
    {
        $batchModel = BatchModel::where('user_id', $this->_user->id)
          ->where('source_filename is not null')
          ->order('id', 'desc')->order('filename', 'desc')->select();
        $data = [];
        foreach ($batchModel as $b) {
            $item = [
                    'id' => $b->id,
                    'name'  => $b->score_header,
                    'task_id' => $b->task_id,
                    'create_time' => date('m/d H:i', $b->createtime),
                    'end_time' => !empty($b->over_time) ? date('m/d H:i', $b->over_time) : '--',
                    'total_records' => $b->total_records,
                    'success_records' => !empty($b->over_time) ? $b->success_records : '-',
                    'error_records' => !empty($b->over_time) ? $b->fail_records : '-',
                    'download_url' => !empty($b->filename) ? cdnurl($b->filename, true) : '',
                ];
            $data[] = $item;
        }

        $this->success('ok', $data);
    }

    public function delBatch()
    {
        $id = $this->request->get('id'); 
        if (empty($id)) {
            $this->error('缺少参数');
        }
        $batchModel = BatchModel::get($id);
        if (empty($batchModel)) {
            $this->error('无对应记录');
        }
        $batchModel->delete();
        $this->success('删除成功');
    }

    public function delScore()
    {
        $scoreId = $this->request->get('id', 0);
        $scoreUser = ScoreUserModel::where('id', $scoreId)->where('user_id', $this->_user->id)->find();
        if (empty($scoreUser)) {
            $this->error('无评分数据');
        }
        $scoreUser->delete();
        $sportUserId = $scoreUser->id;
        ScoreUserDetailModel::where('sport_user_id', $sportUserId)->delete();
        $this->success(__('操作成功'));
    }

    public function saveScore()
    {
        if (!$this->request->isPost()) {
            $this->error(__('Invalid parameters'));
        }

        $scores = $this->request->post('scores/a'); 
        // 暂时由计算得出，屏蔽掉此获取
        // $scoreTotal = $this->request->post('score_total', '0');
        $areaId = $this->request->post('area_id', 0);
        $scoreType = $this->request->post('score_type', '');
        $sex = $this->request->post('sex', 1);
        if (empty($scores)) {
            $this->error('缺少分数参数');
        }
        if (empty($sex)) {
            $this->error('缺少性别参数');
        }
        /*
        if (empty($scoreTotal)) {
            $this->error('缺少总分参数');
        }
         */
        if (empty($areaId) || empty($scoreType)) {
            $this->error('缺少地区或类别参数');
        }
        $itemTotal = 0;
        $newScores = [];
        foreach ($scores as $s) {
            // 没有传入成绩
            if (!empty($s['score'])) {
                $itemTotal++;
                $newScores[] = $s;
            }
        }
        $scores = $newScores;
        // scoreTotal需要通过计算给出
        // 每次进行一次计算，满足条件时就给评级
        $level = [ 
            'score_total' => 0,
            'level_code' => '无',
            'level_name' => '无',
        ];
        $scoreLib = new ScoreLib();
        $calRes = $scoreLib->calScore($scores, $areaId, $scoreType, $sex);
        // 计算没错误时给出评级
        $scoreTotal = 0;
        if (empty($calRes['msg'])) {
            $scoreTotal = $calRes['res']['score_total'];
        }
        $scoreItems = $calRes['score_items'];
        $newScoreItems = [];
        foreach ($scoreItems as $si) {
            $newScoreItems[$si['score_id']] = $si;
        }

        // 是否有传递反馈内容和教师
        // 增加自动反馈
        $feedbacks = $scoreLib->createAutoFeedback(0, $scores);
        $feedback = $feedbacks[0];
        $teacherId = input('post.teacher_id', 0);

        // 判断是否有提交过成绩
        $scoreUser = ScoreUserModel::where('user_id', $this->_user->id)->where('sport_area_id', $areaId)
          ->where('score_type', $scoreType)->where('sex', $sex)->find();
        if (!$scoreUser) {
            $scoreUser = new ScoreUserModel(); 
            $scoreUser->user_id = $this->_user->id;
            $scoreUser->sport_area_id = $areaId;
            $scoreUser->score_type = $scoreType;
            $scoreUser->sex = $sex;
            $scoreUser->score_total = $scoreTotal;
            $scoreUser->items_total = $itemTotal;
            if (!empty($feedback)) {
                $scoreUser->feedback_content = $feedback;
                $scoreUser->feedback_status = 2;
            }
            if (!empty($teacherId)) {
                $scoreUser->sport_teacher_id = $teacherId;
            }
            $scoreUser->save();
        } else {
            $scoreUser->score_total = $scoreTotal;
            $scoreUser->items_total = $itemTotal;
            if (!empty($feedback)) {
                $scoreUser->feedback_content = $feedback;
                $scoreUser->feedback_status = 2;
            }
            $scoreUser->save();
        }
        $sportUserId = $scoreUser->id;
        ScoreUserDetailModel::where('sport_user_id', $sportUserId)->delete();
        foreach ($scores as $s) {
            if (!empty($s['score'])) {
                // 转换一次后存储
                $scoreRes = [$s['score'], $s['score']];
                if (isset($newScoreItems[$s['sport_score_id']])) {
                    $scoreRes = $scoreLib->convertScore($s['score'], $newScoreItems[$s['sport_score_id']]['unit'], $newScoreItems[$s['sport_score_id']]['show_unit']);
                }
                $scoreUserDetail = new ScoreUserDetailModel(); 
                $scoreUserDetail->sport_user_id = $sportUserId;
                $scoreUserDetail->sport_score_id = $s['sport_score_id'];
                $scoreUserDetail->score = $scoreRes[1];
                $scoreUserDetail->show_score = $scoreRes[1];
                $scoreUserDetail->point = $s['point'];
                $scoreUserDetail->unit = $s['unit'];
                $scoreUserDetail->save();
            }
        }
    
        $this->success(__('保存成功'));
    }

    public function scoreList()
    {
        $res = [];
        $scores = ScoreUserModel::where('user_id', $this->_user->id)->with('area')->select();
        if (!empty($scores)) {
            foreach ($scores as $s) {
                $tmp = [
                    'id' => $s->id,
                    'score_type' => $s->score_type,
                    'name'  => $s->area->area_name . $this->scoreTypes[$s->score_type],
                    'sex'   => $this->sexs[$s->sex],
                    'items_total' => $s->items_total,
                    'score_total' => empty($s->score_total) ? '暂无' : $s->score_total,
                    'feedback_status' => $s->feedback_status,
                    'update_time' => date('m/d', $s->updatetime),
                ];

                $res[] = $tmp;
            }
        }
        $this->success('获取成功', $res);
    }

    public function getScoreDetail()
    {
        $id = $this->request->get('id', 0);
        if (empty($id)) {
            $this->error('缺少参数');
        }
        $score = ScoreUserModel::where('s_user.id', $id)->where('user_id', $this->_user->id)->with(['area', 'teacher'])->find();
        if (empty($score)) {
            $this->error('无评分数据');
        }
        $res = [];
        $openKf = 0;
        if ($score->feedback_status == '2') {
            $openKf = 1;
        }
        $teacher = $score->teacher;
        $teacher['icon_image'] =  cdnurl($teacher['icon_image'], true);
        $scoreUser = [
            'id' => $score->id,
            'name'  => $score->area->area_name . $this->scoreTypes[$score->score_type],
            'sex'   => $score->sex,
            'score_total' => $score->score_total,
            'feedback_status' => $score->feedback_status,
            'feedback_content' => $score->feedback_content,
            'area_id' => $score->sport_area_id,
            'level_code' => $score->score_level,
            'teacher' => $teacher,
        ];
        $scoreItems = ScoreUserDetailModel::where('sport_user_id', $id)->with('item')->select();
        $items = [];
        $scoreIds = [];
        // 要计算的项
        $calScores = [];
        foreach ($scoreItems as $si) {
            if (!empty($si->item) && isset($this->units[$si->item->unit])) {
                $items[$si->item->id] = [
                    'score_id' => $si->item->id,
                    'project_name' => $si->item->project_name,
                    'unit'  => $si->item->unit,
                    'unit_name' => $this->units[$si->item->unit],
                    'show_unit' => !empty($si->item->show_unit) ? $si->item->show_unit : $this->units[$si->item->unit],
                    'show_val' => !empty($si->item->show_val) ? $si->item->show_val : '0',
                    'score' => empty($si->show_score) ? $si->score : $si->show_score,
                    'point' => $si->point,
                    'type_id' => 0,
                ];
                $scoreIds[] = $si->item->id;
                $calScores[] = [
                    "sport_score_id"=> $si->sport_score_id,
                    "point"=> $si->point,
                    "score"=> $si->score,
                    "unit"=> $si->item->unit,
                ];
            }
        }


        if ($score->score_type == 'middle') {
            // 查找score list
            $scores = ScoreModel::where('status', 'normal')
                                ->where('id', 'in', $scoreIds)
                                ->select();
            foreach ($scores as $s) {
                if (isset($items[$s->id])) {
                    $items[$s->id]['type_id'] = $s->sport_type_id;
                }
            }

            // 先查找项目类别
            $types = [];
            $typeNames = [];
            $scoreTypes = ScoreTypeModel::where('sport_area_id', $score->sport_area_id)->where('status', 'normal')->select();
            foreach ($scoreTypes as $st) {
                $types[$st->id]  = [];  
                $typeNames[$st->id] = $st->type_name;
            }

            $scoreRes = [];
            foreach ($items as $s) {
                if (isset($types[$s['type_id']]))  {
                    $types[$s['type_id']][] = $s;
                } 
            }
            foreach ($types as $typeId => $t) {
                if (!empty($t)) {
                    $scoreRes[] = [
                      'name' => $typeNames[$typeId],
                      'list' => $t,
                    ];
                }
            }
        } else {
            // 高考体育项
            $scores = [];
            foreach ($items as $s) {
                // $scores[] = $s;
                $scoreRes[] = [
                  'name' => '',
                  'list' => [$s],
                ];
            }
        }

        // 每次进行一次计算，满足条件时就给评级
        $level = [ 
            'score_total' => 0,
            'level_code' => '无',
            'level_name' => '无',
        ];
        $scoreLib = new ScoreLib();
        $areaId = $score->sport_area_id;
        $scoreType = $score->score_type;
        $sex = $score->sex;
        $calRes = $scoreLib->calScore($calScores, $areaId, $scoreType, $sex);
        // 计算没错误时给出评级
        if (empty($calRes['msg'])) {
            $level = $calRes['res'];
        }

        $res['score_user'] = $scoreUser;
        $res['items'] = $scoreRes;
        $res['level'] = $level;
        $res['open_kf'] = $openKf;

        $this->success('获取成功', $res);
    }

    public function questionOnce()
    {
        $id = $this->request->get('id', 0);
        if (empty($id)) {
            $this->error('缺少参数');
        }
        $score = ScoreUserModel::where('id', $id)->where('user_id', $this->_user->id)->find();
        if (empty($score)) {
            $this->error('无评分数据');
        }
        if ($score->feedback_status == 2) {
            $this->success('ok', ['open_kf' => 1]);
        } else {
            // 自动给出反馈
            // 根据分数自动给出反馈
            $scoreLib = new ScoreLib();
            $feedbacks = $scoreLib->createAutoFeedback($id);
            $msg = '提交成功，请等待反馈';
            if (empty($feedbacks[0])) {
                $score->feedback_status = 1;
            } else {
                $msg = '咨询已处理';
                $score->feedback_content = $feedbacks[0];
                $score->sport_teacher_id = $feedbacks[1];
                $score->feedback_status = 2;
            }
            $score->save();
            $this->success($msg, ['open_kf' => 0]);
        }
    }

    private function _checkBatch()
    {
        if ($this->_user->batch_op != '1') {
            $res = [];
            $res['qr_code'] = cdnurl(SettingModel::getSingleSetting('private_teacher'), true);
            $this->error('暂时无批量处理权限', $res);
        } 
    
    }

    //**********************************

    /**
     * 会员中心
     */
    public function index()
    {
        $this->success('', ['welcome' => $this->auth->nickname]);
    }

    /**
     * 退出登录
     * @ApiMethod (POST)
     */
    public function logout()
    {
        if (!$this->request->isPost()) {
            $this->error(__('Invalid parameters'));
        }
        $this->auth->logout();
        $this->success(__('Logout successful'));
    }

    /**
     * 修改会员个人信息
     *
     * @ApiMethod (POST)
     * @ApiParams (name="avatar", type="string", required=true, description="头像地址")
     * @ApiParams (name="username", type="string", required=true, description="用户名")
     * @ApiParams (name="nickname", type="string", required=true, description="昵称")
     * @ApiParams (name="bio", type="string", required=true, description="个人简介")
     */
    public function profile()
    {
        $user = $this->auth->getUser();
        $username = $this->request->post('username');
        $nickname = $this->request->post('nickname');
        $gender = $this->request->post('gender');
        $birthday = $this->request->post('birthday');
        $phone = $this->request->post('phone');
        $avatar = $this->request->post('avatar', '/assets/img/avatar.png', 'trim,strip_tags,htmlspecialchars');
        if ($username) {
            $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
            if ($exists) {
                $this->error(__('Username already exists'));
            }
            $user->username = $username;
        }
        if ($nickname) {
            $exists = \app\common\model\User::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find();
            if ($exists) {
                $this->error(__('Nickname already exists'));
            }
            $user->nickname = $nickname;
        }
        if ($phone) {
            $exists = \app\common\model\User::where('mobile', $phone)->where('id', '<>', $this->auth->id)->find();
            if ($exists) {
                $this->error(__('手机已存在'));
            }
            $user->mobile = $phone;
        }
        $user->gender = $gender;
        $user->birthday = $birthday;
        $user->avatar = $avatar;
        $user->save();
        $this->success();
    }

    public function mpWeixinDecodePhone()
    {

        if ($this->request->isPost()) {

            $user = $this->auth->getUser();

            $encryptedData = $this->request->post('encryptedData');
            $iv = $this->request->post('iv');
            $doSet = $this->request->post('doSet', 0); //是否保存

            $mpAppid = Env::get('mp.appid');
            $mpAppSecret = Env::get('mp.app_secret');

            $config = [
                'app_id' => $mpAppid,
                'secret' => $mpAppSecret,

                'response_type' => 'array',
                'log' => [
                    'level' => 'debug',
                    'file' => ROOT_PATH . '/runtime/log/wechat.log',
                ],
            ];

            try {
                $app = Factory::miniProgram($config);

                $sessionkey = Third::where('user_id', $user->id)->find()->sessionkey;

                $decryptedData = $app->encryptor->decryptData($sessionkey, $iv, $encryptedData);

                if ($doSet) {
                    $user->mobile = $decryptedData['phoneNumber'];
                    $user->save();
                }

            } catch (\Exception $e) {

                $this->error($e->getMessage(), null, 401);
            }

            $this->success('ok', ['phone' => $decryptedData['phoneNumber']]);
        }
    }


    //**********************************

    /**
     * 会员登录
     *
     * @ApiMethod (POST)
     * @ApiParams (name="account", type="string", required=true, description="账号")
     * @ApiParams (name="password", type="string", required=true, description="密码")
     */
    public function login()
    {
        $account = $this->request->post('account');
        $password = $this->request->post('password');
        if (!$account || !$password) {
            $this->error(__('Invalid parameters'));
        }
        $ret = $this->auth->login($account, $password);
        if ($ret) {
            $data = ['userinfo' => $this->auth->getUserinfo()];
            $this->success(__('Logged in successful'), $data);
        } else {
            $this->error($this->auth->getError());
        }
    }

    /**
     * 手机验证码登录
     *
     * @ApiMethod (POST)
     * @ApiParams (name="mobile", type="string", required=true, description="手机号")
     * @ApiParams (name="captcha", type="string", required=true, description="验证码")
     */
    public function mobilelogin()
    {
        $mobile = $this->request->post('mobile');
        $captcha = $this->request->post('captcha');
        if (!$mobile || !$captcha) {
            $this->error(__('Invalid parameters'));
        }
        if (!Validate::regex($mobile, "^1\d{10}$")) {
            $this->error(__('Mobile is incorrect'));
        }
        if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
            $this->error(__('Captcha is incorrect'));
        }
        $user = \app\common\model\User::getByMobile($mobile);
        if ($user) {
            if ($user->status != 'normal') {
                $this->error(__('Account is locked'));
            }
            //如果已经有账号则直接登录
            $ret = $this->auth->direct($user->id);
        } else {
            $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
        }
        if ($ret) {
            Sms::flush($mobile, 'mobilelogin');
            $data = ['userinfo' => $this->auth->getUserinfo()];
            $this->success(__('Logged in successful'), $data);
        } else {
            $this->error($this->auth->getError());
        }
    }

    /**
     * 注册会员
     *
     * @ApiMethod (POST)
     * @ApiParams (name="username", type="string", required=true, description="用户名")
     * @ApiParams (name="password", type="string", required=true, description="密码")
     * @ApiParams (name="email", type="string", required=true, description="邮箱")
     * @ApiParams (name="mobile", type="string", required=true, description="手机号")
     * @ApiParams (name="code", type="string", required=true, description="验证码")
     */
    public function register()
    {
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        $email = $this->request->post('email');
        $mobile = $this->request->post('mobile');
        $code = $this->request->post('code');
        if (!$username || !$password) {
            $this->error(__('Invalid parameters'));
        }
        if ($email && !Validate::is($email, "email")) {
            $this->error(__('Email is incorrect'));
        }
        if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
            $this->error(__('Mobile is incorrect'));
        }
        $ret = Sms::check($mobile, $code, 'register');
        if (!$ret) {
            $this->error(__('Captcha is incorrect'));
        }
        $ret = $this->auth->register($username, $password, $email, $mobile, []);
        if ($ret) {
            $data = ['userinfo' => $this->auth->getUserinfo()];
            $this->success(__('Sign up successful'), $data);
        } else {
            $this->error($this->auth->getError());
        }
    }


    /**
     * 修改邮箱
     *
     * @ApiMethod (POST)
     * @ApiParams (name="email", type="string", required=true, description="邮箱")
     * @ApiParams (name="captcha", type="string", required=true, description="验证码")
     */
    public function changeemail()
    {
        $user = $this->auth->getUser();
        $email = $this->request->post('email');
        $captcha = $this->request->post('captcha');
        if (!$email || !$captcha) {
            $this->error(__('Invalid parameters'));
        }
        if (!Validate::is($email, "email")) {
            $this->error(__('Email is incorrect'));
        }
        if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) {
            $this->error(__('Email already exists'));
        }
        $result = Ems::check($email, $captcha, 'changeemail');
        if (!$result) {
            $this->error(__('Captcha is incorrect'));
        }
        $verification = $user->verification;
        $verification->email = 1;
        $user->verification = $verification;
        $user->email = $email;
        $user->save();

        Ems::flush($email, 'changeemail');
        $this->success();
    }

    /**
     * 修改手机号
     *
     * @ApiMethod (POST)
     * @ApiParams (name="mobile", type="string", required=true, description="手机号")
     * @ApiParams (name="captcha", type="string", required=true, description="验证码")
     */
    public function changemobile()
    {
        $user = $this->auth->getUser();
        $mobile = $this->request->post('mobile');
        $captcha = $this->request->post('captcha');
        if (!$mobile || !$captcha) {
            $this->error(__('Invalid parameters'));
        }
        if (!Validate::regex($mobile, "^1\d{10}$")) {
            $this->error(__('Mobile is incorrect'));
        }
        if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
            $this->error(__('Mobile already exists'));
        }
        $result = Sms::check($mobile, $captcha, 'changemobile');
        if (!$result) {
            $this->error(__('Captcha is incorrect'));
        }
        $verification = $user->verification;
        $verification->mobile = 1;
        $user->verification = $verification;
        $user->mobile = $mobile;
        $user->save();

        Sms::flush($mobile, 'changemobile');
        $this->success();
    }

    /**
     * 第三方登录
     *
     * @ApiMethod (POST)
     * @ApiParams (name="platform", type="string", required=true, description="平台名称")
     * @ApiParams (name="code", type="string", required=true, description="Code码")
     */
    public function third()
    {
        $url = url('user/index');
        $platform = $this->request->post("platform");
        $code = $this->request->post("code");
        $config = get_addon_config('third');
        if (!$config || !isset($config[$platform])) {
            $this->error(__('Invalid parameters'));
        }
        $app = new \addons\third\library\Application($config);
        //通过code换access_token和绑定会员
        $result = $app->{$platform}->getUserInfo(['code' => $code]);
        if ($result) {
            $loginret = \addons\third\library\Service::connect($platform, $result);
            if ($loginret) {
                $data = [
                    'userinfo'  => $this->auth->getUserinfo(),
                    'thirdinfo' => $result
                ];
                $this->success(__('Logged in successful'), $data);
            }
        }
        $this->error(__('Operation failed'), $url);
    }

    /**
     * 重置密码
     *
     * @ApiMethod (POST)
     * @ApiParams (name="mobile", type="string", required=true, description="手机号")
     * @ApiParams (name="newpassword", type="string", required=true, description="新密码")
     * @ApiParams (name="captcha", type="string", required=true, description="验证码")
     */
    public function resetpwd()
    {
        $type = $this->request->post("type", "mobile");
        $mobile = $this->request->post("mobile");
        $email = $this->request->post("email");
        $newpassword = $this->request->post("newpassword");
        $captcha = $this->request->post("captcha");
        if (!$newpassword || !$captcha) {
            $this->error(__('Invalid parameters'));
        }
        //验证Token
        if (!Validate::make()->check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,30}'])) {
            $this->error(__('Password must be 6 to 30 characters'));
        }
        if ($type == 'mobile') {
            if (!Validate::regex($mobile, "^1\d{10}$")) {
                $this->error(__('Mobile is incorrect'));
            }
            $user = \app\common\model\User::getByMobile($mobile);
            if (!$user) {
                $this->error(__('User not found'));
            }
            $ret = Sms::check($mobile, $captcha, 'resetpwd');
            if (!$ret) {
                $this->error(__('Captcha is incorrect'));
            }
            Sms::flush($mobile, 'resetpwd');
        } else {
            if (!Validate::is($email, "email")) {
                $this->error(__('Email is incorrect'));
            }
            $user = \app\common\model\User::getByEmail($email);
            if (!$user) {
                $this->error(__('User not found'));
            }
            $ret = Ems::check($email, $captcha, 'resetpwd');
            if (!$ret) {
                $this->error(__('Captcha is incorrect'));
            }
            Ems::flush($email, 'resetpwd');
        }
        //模拟一次登录
        $this->auth->direct($user->id);
        $ret = $this->auth->changepwd($newpassword, '', true);
        if ($ret) {
            $this->success(__('Reset password successful'));
        } else {
            $this->error($this->auth->getError());
        }
    }
}
